package top.lyf1210.yuwenpicturebackend.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.stereotype.Service;
import top.lyf1210.yuwenpicturebackend.exception.BusinessException;
import top.lyf1210.yuwenpicturebackend.exception.ErrorCode;
import top.lyf1210.yuwenpicturebackend.exception.ThrowUtils;
import top.lyf1210.yuwenpicturebackend.model.Picture;
import top.lyf1210.yuwenpicturebackend.model.Space;
import top.lyf1210.yuwenpicturebackend.model.User;
import top.lyf1210.yuwenpicturebackend.model.dto.analyze.*;
import top.lyf1210.yuwenpicturebackend.model.vo.analyze.*;
import top.lyf1210.yuwenpicturebackend.service.PictureService;
import top.lyf1210.yuwenpicturebackend.service.SpaceAnalyzeService;
import top.lyf1210.yuwenpicturebackend.service.SpaceService;
import top.lyf1210.yuwenpicturebackend.service.UserService;
import top.lyf1210.yuwenpicturebackend.utils.DataStatisticUtils;
import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassNameSpaceAnalyzeServiceImpl
 * @Description TODO
 * @Author钰玟
 * @Date2025/5/21 下午7:53
 * @Version 1.0
 **/
@Service
public class SpaceAnalyzeServiceImpl  implements SpaceAnalyzeService {
    @Resource
    private UserService userService;
    @Resource
    private SpaceService spaceService;
    @Resource
    private PictureService pictureService;

    @Resource
    private DataStatisticUtils dataStatisticUtils;
    @Override
    public void checkSpaceAnalyzeAuth(SpaceAnalyzeRequest spaceAnalyzeRequest, User loginUser) {
        //1.校验权限
        //2. 公共图库的数据分析
        if(spaceAnalyzeRequest.isQueryPublic() || spaceAnalyzeRequest.isQueryAll()){
            //只有是管理员才有权限进行分析
            ThrowUtils.throwIf(!userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR,"无权访问公共图库");
        }
        //3. 用户个人的数据分析
        if(spaceAnalyzeRequest.getSpaceId() != null){
            Long spaceId = spaceAnalyzeRequest.getSpaceId();
            //校验spaceId
            ThrowUtils.throwIf(spaceId < 0,ErrorCode.PARAMS_ERROR);
            Space spaceById = spaceService.getById(spaceId);
            ThrowUtils.throwIf(spaceById == null,ErrorCode.NOT_FOUND_ERROR,"空间不存在");
            //校验权限
            spaceService.checkSpaceAuth(spaceById,loginUser);

        }
    }

    @Override
    public SpaceUsageAnalyzeResponse getSpaceUsageAnalyze(SpaceAnalyzeRequest spaceAnalyzeRequest, User loginUser) {
        //1.如果是分析全局空间(即 公共图库)
        if(spaceAnalyzeRequest.isQueryPublic() || spaceAnalyzeRequest.isQueryAll()){
            //则是查询所有的空间
            boolean isAdmin = userService.isAdmin(loginUser);
            ThrowUtils.throwIf(!isAdmin,ErrorCode.NO_AUTH_ERROR,"无权访问公共图库");
            //统计公共图库的资源使用情况
            QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
            //统计的是 图片的 picSize字段
            queryWrapper.select("picSize");
            if(spaceAnalyzeRequest.isQueryPublic()){
                queryWrapper.isNull("spaceId");
            }
            List<Object> pictureObjList = pictureService.getBaseMapper().selectObjs(queryWrapper);
            //统计所有图片的资源使用情况
            long usedSize = pictureObjList.stream().mapToLong(result->
                result instanceof Long ? (long) result : 0).sum();
            long usedCount = pictureObjList.size();
            //封装返回结果
            SpaceUsageAnalyzeResponse spaceUsageAnalyzeResponse = SpaceUsageAnalyzeResponse.builder().build();
            //有效的分析结果
            spaceUsageAnalyzeResponse.setUsedSize(usedSize);
            spaceUsageAnalyzeResponse.setUsedCount(usedCount);
            //公共图库无上限(无效的)
            spaceUsageAnalyzeResponse.setMaxSize(null);
            spaceUsageAnalyzeResponse.setSizeUsageRatio(null);
            spaceUsageAnalyzeResponse.setMaxCount(null);
            spaceUsageAnalyzeResponse.setMaxCount(null);
            //返回结果
            return spaceUsageAnalyzeResponse;
        }
        //2. 如果是分析个人空间
        else{//有spaceId
            Long spaceId = spaceAnalyzeRequest.getSpaceId();
            //判断是否合法
            ThrowUtils.throwIf(spaceId==null,ErrorCode.PARAMS_ERROR);
            Space byId = spaceService.getById(spaceId);
            ThrowUtils.throwIf(byId==null,ErrorCode.NOT_FOUND_ERROR,"空间不存在");
            //权限校验，只有管理员或者空间创建者有权限
            spaceService.checkSpaceAuth(byId,loginUser);
            //使用占比
            double sizeUsageRatio = NumberUtil.round(byId.getTotalSize() * 100.0 / byId.getMaxSize(), 2).doubleValue();
            double countUsageRatio = NumberUtil.round(byId.getTotalCount() * 100.0/ byId.getMaxCount(),2).doubleValue();
            System.err.println("sizeUsageRatio:"+sizeUsageRatio);
            System.err.println("countUsageRatio:"+countUsageRatio);
            return SpaceUsageAnalyzeResponse.builder()
                    //使用数量
                    .usedCount(byId.getTotalCount())
                    .maxCount(byId.getMaxCount())
                    //使用大小
                    .usedSize(byId.getTotalSize())
                    .maxSize(byId.getMaxSize())
                    .sizeUsageRatio(sizeUsageRatio)
                    .countUsageRatio(countUsageRatio)
                    .build();
        }
    }

    /**
     * 分析空间分类
     * @param spaceCategoryAnalyzeRequest 请求dto
     * @param loginUser 用户
     * @return
     */
    @Override
    public List<SpaceCategoryAnalyzeResponse> getSpaceCategoryAnalyze(SpaceCategoryAnalyzeRequest spaceCategoryAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceCategoryAnalyzeRequest==null,ErrorCode.PARAMS_ERROR);
        //检查权限
        checkSpaceAnalyzeAuth(spaceCategoryAnalyzeRequest,loginUser);
        //构造查询条件
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        dataStatisticUtils.fillAnalyzeQueryWrapper(spaceCategoryAnalyzeRequest,queryWrapper);

        //分组查询
        queryWrapper.select(
                "category AS category"
                ,"COUNT(*) as count"
                ,"SUM(picSize) as totalSize"
        ).groupBy("category");
        return pictureService.getBaseMapper().selectMaps(queryWrapper)
                .stream().map(result ->{
                    String category = result.get("category") !=null ? result.get("category").toString(): "未分类";
                    Long count = ((Number)result.get("count")).longValue();
                    Long totalSize = ((Number)result.get("totalSize")).longValue();
                    return new SpaceCategoryAnalyzeResponse(category,count,totalSize);
                }).collect(Collectors.toList());
    }

    /**
     * 标签分析
     * @param spaceTagAnalyzeRequest 请求dto
     * @param loginUser 用户
     * @return
     */
    @Override
    public List<SpaceTagAnalyzeResponse> getSpaceTagAnalyze(SpaceTagAnalyzeRequest spaceTagAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceTagAnalyzeRequest==null,ErrorCode.PARAMS_ERROR);
        //检查权限
        checkSpaceAnalyzeAuth(spaceTagAnalyzeRequest,loginUser);
        //构造查询条件
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        dataStatisticUtils.fillAnalyzeQueryWrapper(spaceTagAnalyzeRequest,queryWrapper);
        queryWrapper.select("tags");
        List<String> tagsJsonList = pictureService.getBaseMapper().selectObjs(queryWrapper)
                .stream()
                .filter(ObjUtil::isNotNull)
                .map(Object::toString).collect(Collectors.toList());
        // 合并所有标签并统计使用次数
        Map<String, Long> tagCountMap = tagsJsonList.stream()
                .flatMap(tagsJson -> JSONUtil.toList(tagsJson, String.class).stream())
                .collect(Collectors.groupingBy(tag -> tag, Collectors.counting()));

        // 转换为响应对象，按使用次数降序排序
        return tagCountMap.entrySet().stream()
                .sorted((e1, e2) -> Long.compare(e2.getValue(), e1.getValue())) // 降序排列
                .map(entry -> new SpaceTagAnalyzeResponse(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());

    }

    @Override
    public List<SpaceSizeAnalyzeResponse> getSpaceSizeAnalyze(SpaceSizeAnalyzeRequest spaceSizeAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceSizeAnalyzeRequest==null,ErrorCode.PARAMS_ERROR);
        //检查权限
        checkSpaceAnalyzeAuth(spaceSizeAnalyzeRequest,loginUser);
        //构造查询条件
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        dataStatisticUtils.fillAnalyzeQueryWrapper(spaceSizeAnalyzeRequest,queryWrapper);

        queryWrapper.select("picSize");
        List<Long> picSizes = pictureService.getBaseMapper().selectObjs(queryWrapper)
                .stream()
                .filter(ObjUtil::isNotNull)
                .map(size -> ((Number) size).longValue())
                .collect(Collectors.toList());
        // 定义分段范围，注意使用有序 Map
        Map<String, Long> sizeRanges = new LinkedHashMap<>();
        sizeRanges.put("<100KB", picSizes.stream().filter(size -> size < 100 * 1024).count());
        sizeRanges.put("100KB-500KB", picSizes. stream().filter(size -> size >= 100 * 1024 && size < 500 * 1024).count());
        sizeRanges.put("500KB-1MB", picSizes.stream().filter(size -> size >= 500 * 1024 && size < 1 * 1024 * 1024).count());
        sizeRanges.put(">1MB", picSizes.stream().filter(size -> size >= 1 * 1024 * 1024).count());


        return sizeRanges.entrySet().stream()
                .map(entry->new SpaceSizeAnalyzeResponse(entry.getKey(),entry.getValue()))
                .collect(Collectors.toList());
    }

    @Override
    public List<SpaceUserAnalyzeResponse> getSpaceUserAnalyze(SpaceUserAnalyzeRequest spaceUserAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceUserAnalyzeRequest==null,ErrorCode.PARAMS_ERROR);
        //检查权限
        checkSpaceAnalyzeAuth(spaceUserAnalyzeRequest,loginUser);
        //构造查询条件
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        dataStatisticUtils.fillAnalyzeQueryWrapper(spaceUserAnalyzeRequest,queryWrapper);
        Long userId = spaceUserAnalyzeRequest.getUserId();
        queryWrapper.eq(ObjUtil.isNotNull(userId), "userId", userId);
        // 分析维度：每日、每周、每月
        String timeDimension = spaceUserAnalyzeRequest.getTimeDimension();
        switch (timeDimension) {
            case "day":
                queryWrapper.select("DATE_FORMAT(createTime, '%Y-%m-%d') AS period", "COUNT(*) AS count");
                break;
            case "week":
                queryWrapper.select("YEARWEEK(createTime) AS period", "COUNT(*) AS count");
                break;
            case "month":
                queryWrapper.select("DATE_FORMAT(createTime, '%Y-%m') AS period", "COUNT(*) AS count");
                break;
            default:
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "不支持的时间维度");
        }

        // 分组和排序
        queryWrapper.groupBy("period").orderByAsc("period");

        // 查询结果并转换
        List<Map<String, Object>> queryResult = pictureService.getBaseMapper().selectMaps(queryWrapper);
        return queryResult.stream()
                .map(result -> {
                    String period = result.get("period").toString();
                    Long count = ((Number) result.get("count")).longValue();
                    return new SpaceUserAnalyzeResponse(period, count);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<Space> getSpaceRankAnalyze(SpaceRankAnalyzeRequest spaceRankAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceRankAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);

        // 仅管理员可查看空间排行
        ThrowUtils.throwIf(!userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR, "无权查看空间排行");

        // 构造查询条件
        QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "spaceName", "userId", "totalSize")
                .orderByDesc("totalSize")
                .last("LIMIT " + spaceRankAnalyzeRequest.getTopN()); // 取前 N 名

        // 查询结果
        return spaceService.list(queryWrapper);
    }

}
